﻿Flag evaluation
———————————————

Below is an explanation of how to implement the correct flag evaluation for:

1) NMOS/CMOS binary mode and CMOS two-cycle BCD mode
2) NMOS decimal ADC/SBC
3) ANC and ARR illegal opcodes

The concept is based on the assumption that we use a 74541 based
2:1 multiplexer in front of the BCD correction adders for shifting
right if there is an ARR instruction... for having ARR in decimal mode.

First some theory about the V_Flag;

V_Flag:

VEVALUATE

Current schematics:

  Y = (W7 * /R7 * /Y7) + (/W7 * R7 * Y7)

  Connections:

  select: A = W7, B = R7, C = Y7
  data:   D7..0 = 0,1,0,0, 0,0,1,0

Now for a different approach.

  We could use a NOR gate and an AND gate fed by R7 and Y7.
  Those gates won't be in the critical delay path because
  they are faster than the ADDR adders which generate W7.

  V0 =  R7 *  Y7                //AND
  V1 = /R7 * /Y7 = /(R7 + Y7)   //NOR

  So if we would have a 2:1 multiplexer controlled by W7,
  we could connect D0 to V0, D1 to V1, for generating V.

 When taking a look at ARR in binary mode:

 Y7..0 = ADR 7..0

 V = W6   XOR W5   //after  shifting right
 V = ADR7 XOR ADR6 //before shifting right
 V = Y7   XOR Y6   //before shifting right, less propagation delay.

;===

Now for the implementation.

Some control signals:

 BCD.NMOS is active for 6510 and NMOS 6502 ADC\SBC in decimal mode.

 ARNC active on ARR or ANC opcode ($0B or $6B)
 ARR = (ARNC * OP6)
 
 
 PPW = (P.W OR ARNC)
 SSF = (SF  OR ARRANC)

;---

V_Flag:

 Modifying VEVALUATE:

  V0 = R7 AND Y7
  V1 = R7 NOR Y7

  select: A = W7, B = ADR7, C=BCD.NMOS
  data:   D7..0 = V1,V1,V0,V0, V1,V0,V1,V0.

 Logic Summary:
	
	For /BCD.NMOS, /W7 -> V0, W7 -> V1

	For BCD.NMOS, /ADR7 -> V0, ADR7 -> V1


 Modifying VSELECTOR: // (Y7 XOR Y6) is ARR V.

  select: A = /BIT, B = SSF, C = PPW
  data:   D7..0 = (Y7 XOR Y6),0,W6,0, W6,0,VEVALUATE,B6

 Logic Summary:
	
	(/SSF, /PPW) /BIT -> B6, BIT -> VEVALUATE
 
	(BIT) SSF -> W6, (BIT) PPW -> W6

	(BIT) SSF * PPW = (ARR OR ANC) -> (Y7 XOR Y6)

	But since ANC opcode does not set V, it’s an ARR

;---

C_Flag:

 Modifying CSELECTOR:

  select: A = LSR, B = SSF, C = PPW
  data:   D7..0 = 0,ADR7,0,W0, 0,W0,ADR0,ADRC


 Logic Summary:
	(/SSF * /PPW) /LSR -> ADRC, LSR -> ADR0
	(/LSR) SSF -> W0, PPW -> W0, SSF * PPW = (ARR OR ANC) -> ADR7

;---

It would be neccessary to split N selector and Z selector from 1*74153
into 2*74151, sorry.

N_Flag: 

 NSELECTOR: //74151

  select: A = /BIT, B = ARR, C = BCD.NMOS
  data:   D7..0 = 0,0,ADR7,0, C,0,W7,B7 //C is CZA output, the 7474 C flag.

// Logic summary:
// 000 BIT: N_flag = memory Bit 7, that's B7.
// 001 no BIT, no ARR, no ANC, no NMOS ADC\SBC: should be W7.
// 010 BIT won't be active together with ARR\ANC: unused input, can stay 0.
// 011 ARR: N = C (ANC: N = W7)
// 100 BIT won't be active together with BCD.NMOS: unused input, can stay 0.
// 101 BCD.NMOS: N = ADR7
// 110 BIT won't be active together with ARR\ANC and BCD.NMOS: unused input, can stay 0.
// 111 ARR won't be active together with BCD.NMOS: unused input, can stay 0.

;——

Z_Flag:

I would suggest to have:

 1*7427 at W7..0 plus 1/3*7411 for generating ALUW.Z,
 1*7427 at the inputs of the BCD correction adders plus 1/3*7411
 for generating ALUA.Z.

 So ALUA.Z checks ADR7..0 for 6502 NMOS ADC\SBC in decimal mode.
 for binary  ARR, ALUA.Z = ALUW.Z.
 for decimal ARR, only ALUA.Z is correct.
 For ANC, both ALUW.Z and ALUA.Z would work.

 Here we go:
 Z_SELECTOR: //74151

  select: A = BCD.NMOS, B = ANC, C = P.W
  data:   D7..0 = 0,0,0,W1, 0,ALUA.Z,ALUA.Z,ALUW.Z

// Logic summary:
// 000 no BCD.NMOS, no ARR, no ANC, no P write: Z = ALUW.Z //evaluate Z from W bus
// 001 BCD.NMOS: Z = ALUA.Z //evaluate Z from ADR7..0
// 010 ANC: means ARR OR ANC; Z = ALUA.Z works for binary and decimal ARR. Both ALUA.Z and ALUW.Z would work for ANC. So, ALUA.Z works for both.
// 011 BCD.NMOS won't be active together with ARR or ANC: unused input, can be 0.
// 100 write P: Z = W1.
// 1xx write P won't be active together with BCD.NMOS, ARR, ANC: unused inputs, can be 0.